home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / ppcuuwos.lha / PPCUUEncode.c < prev    next >
C/C++ Source or Header  |  1998-02-18  |  4KB  |  176 lines

  1.  
  2. /*
  3.  * uuencode >outfile [infile] name
  4.  *
  5.  * Encode a file so it can be mailed to a remote system.  This version
  6.  * transparantly adds line checksums and a file size for sanity checks.
  7.  *
  8.  */
  9.  
  10. /* Modified by Steffen P. Häuser (ELF-Version was from Andreas Kleinert)
  11.  *
  12.  * 18.02.98: - WarpOS (TM) version, compiled with StormC, as ELF sucks :)
  13.  *
  14.  * 07.02.98: - powerUP (TM) version, compiled with SAS/C for PPC
  15.  *
  16.  * 31.08.97: - reworked for SAS/C 6.58
  17.  *           - better compiler settings
  18.  *           - ANSI-fied
  19.  *
  20.  * 04.08.94: - first, internal version
  21.  *
  22.  *
  23.  * Original authors:
  24.  *
  25.  * Written by Mark Horton
  26.  * Modified by ajr (Alan J Rosenthatl,flaps@utcsri.UUCP) to use checksums
  27.  * Modified by fnf (Fred Fish,well!fnf) to use Keith Pyle's suggestion for
  28.  * compatibility
  29.  * Modified by bcn (Bryce Nesbitt,ucbvax!hoser!bryce) to enable CTRL-C for
  30.  * Amiga Lattice C.  Added a transparent file size trailer for later check.
  31.  * Changed fopen from "r" to "rb" for Messy-dos machines (thanks to Andrew
  32.  * Wylie)
  33.  */
  34.  
  35. #define __USE_SYSBASE
  36.  
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40.  
  41. #include <sys/types.h>
  42. #include <sys/stat.h>
  43.  
  44. #include <exec/types.h>
  45.  
  46. #include <clib/exec_protos.h>
  47.  
  48.  
  49. LONG filemode(FILE *in);
  50. void encode(FILE *in, FILE *out);
  51. LONG outdec(UBYTE *p, FILE *f);
  52. LONG fr(FILE *fd, UBYTE *buf, LONG cnt);
  53.  
  54. LONG totalsize = 0; /* Used to count the file size because ftell() does
  55.                        not return sane results for pipes */
  56.  
  57. UBYTE version [] = "\0$VER: uuencode 1.0 (7.2.98)";
  58.  
  59. long main(long argc, char **argv)
  60. {
  61.     FILE *in;
  62.     LONG mode;
  63.  
  64.         /* optional 1st argument */
  65.         if (argc > 2) {
  66.                 if ((in = fopen(argv[1], "r")) == NULL) {
  67.                         fprintf(stderr, "ERROR: can't find %s\n", argv[1]);
  68.                         fprintf(stderr, "USAGE: uuencode >outfile [infile] name\n");
  69.                         exit(20);
  70.                 }
  71.                 argv++; argc--;
  72.         } else
  73.                 in = stdin;
  74.  
  75.         if (argc != 2) {
  76.                 fprintf(stderr, "USAGE: uuencode >outfile [infile] name\n");
  77.                 exit(0);
  78.         }
  79.  
  80.         mode = filemode(in);
  81.  
  82.         printf("\nbegin %o %s\n", mode, argv[1]);
  83.  
  84.         encode(in, stdout);
  85.  
  86.         printf("end\n");
  87.         printf("size %ld\n",totalsize);
  88.         exit(0);
  89. }
  90.  
  91. LONG filemode(FILE *in)
  92. {
  93. #ifdef unix_stat
  94.     struct stat sbuf;
  95.         
  96.     fstat(fileno(in), &sbuf);
  97.     return( sbuf.st_mode & 0777); /* figure out the input file mode */
  98.  
  99. #else
  100.     return( 0644 );               /* Default permissions */
  101. #endif
  102. }
  103.  
  104. #define SUMSIZE 64  /* 6 bits */
  105. /* ENC is the basic 1 character encode function to make a char printing */
  106. /* Each output character represents 6 bits of input */
  107. #define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
  108.  
  109. /*
  110.  * copy from in to out, encoding as you go along.
  111.  */
  112. void encode(FILE *in, FILE *out)
  113. {
  114.  extern errno;
  115.  
  116.         LONG i, n, checksum;
  117.         char buf[256];
  118.  
  119.         for (;;) {
  120.                 /* 1 (up to) 45 character line */
  121.                 n = fr(in, buf, 45);
  122.                 putc(ENC(n), out);
  123.  
  124.                 checksum = 0;
  125.                 for (i=0; i<n; i += 3)
  126.                     checksum = (checksum+outdec(&buf[i], out)) % SUMSIZE;
  127.  
  128.                 putc(ENC(checksum), out);
  129.                 putc('\n', out);
  130.  
  131.                 /* Error checking under UNIX?? You must be kidding! */
  132.                 if (errno) {
  133.                     fprintf(stderr, "ERROR: error writing to output\n");
  134.                         exit(20);
  135.                     }
  136.  
  137.                 if (n <= 0)
  138.                         break;
  139.         }
  140. }
  141.  
  142. /*
  143.  * output one group of 3 bytes, pointed at by p, on file f.
  144.  * return the checksum increment.
  145.  */
  146. LONG outdec(UBYTE *p, FILE *f)
  147. {
  148.         LONG c1, c2, c3, c4;
  149.  
  150.         c1 = *p >> 2;
  151.         c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
  152.         c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
  153.         c4 = p[2] & 077;
  154.         putc(ENC(c1), f);
  155.         putc(ENC(c2), f);
  156.         putc(ENC(c3), f);
  157.         putc(ENC(c4), f);
  158.  
  159.         return((p[0]+p[1]+p[2]) % SUMSIZE);
  160. }
  161.  
  162. /* fr: like read but stdio */
  163. LONG fr(FILE *fd, UBYTE *buf, LONG cnt)
  164. {
  165.         LONG c, i;
  166.  
  167.         for (i=0; i<cnt; i++) {
  168.                 c = getc(fd);
  169.                 if (c == EOF)
  170.                         return(i);
  171.                 totalsize++;
  172.                 buf[i] = c;
  173.         }
  174.         return (cnt);
  175. }
  176.